<template>
    <div id="cesium-viewer">
        <div v-if="loading" class="loading-overlay">
            <a-spin tip="加载中..." />
        </div>
        <slot />
    </div>
</template>

<script setup>
import * as Cesium from "cesium";
import { onMounted, markRaw, ref } from "vue";
import { useMapData } from '@/store'

// Cesium token设置
Cesium.Ion.defaultAccessToken = import.meta.env.VITE_CESIUM_TOKEN || "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3ODAzN2EzOS1kZDMzLTQ5Y2UtYjYxMi1jMzQxNTdiMTUzN2IiLCJpZCI6NDU5NDIsImlhdCI6MTYxNTYyNDQyOX0.BucgmI6OJ-7ixj7rcQ_Qyg45DkvdHmaLrFwyMYitLcI";

const dataStore = useMapData()
const loading = ref(false)

// 初始化地图场景
const initViewer = (container) => {
    try {
        const viewer = new Cesium.Viewer(container, {
            timeline: false,
            animation: false,
            baseLayerPicker: false,
            infoBox: false,
            selectionIndicator: false,
            skyAtmosphere: false,
            homeButton: false,
            fullscreenButton: false,
            geocoder: false,
            sceneModePicker: false,
            shouldAnimate: true,
            navigationHelpButton: false,
        })

        const canvas = viewer.scene.canvas
        const ctx = canvas.getContext("2d", { willReadFrequently: true })

        return viewer
    } catch (error) {
        console.error('初始化地图场景失败:', error)
        throw error
    }
}

// 设置场景效果
const setScene = (viewer) => {
    try {
        // 基础设置
        viewer.scene.sun.show = false
        viewer.scene.moon.show = false
        viewer.scene.globe.enableLighting = true

        // 泛光设置
        const bloom = viewer.scene.postProcessStages.bloom
        bloom.enabled = false

        // 亮度设置
        var stages = viewer.scene.postProcessStages
        if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
            viewer.resolutionScale = window.devicePixelRatio
        }

        // 开启抗锯齿
        viewer.scene.postProcessStages.fxaa.enabled = true

        // 亮度调整
        viewer.scene.brightness = viewer.scene.brightness ||
            stages.add(Cesium.PostProcessStageLibrary.createBrightnessStage())
        viewer.scene.brightness.enabled = true
        viewer.scene.brightness.uniforms.brightness = 1.2
        viewer.scene.globe.depthTestAgainstTerrain = true
        viewer._cesiumWidget._creditContainer.style.display = "none"

        // 场景设置
        viewer.scene.highDynamicRange = true
        viewer.scene.postProcessStages.bloom.enabled = true
        viewer.scene.postProcessStages.bloom.uniforms.contrast = 255
        viewer.scene.postProcessStages.bloom.uniforms.brightness = 0.02
        viewer.scene.postProcessStages.bloom.uniforms.glowOnly = false
        viewer.scene.postProcessStages.bloom.uniforms.delta = 3.1
        viewer.scene.postProcessStages.bloom.uniforms.sigma = 5
        viewer.scene.postProcessStages.bloom.uniforms.stepSize = 0.6
        viewer.scene.postProcessStages.bloom.uniforms.isSelected = false
        viewer.scene.postProcessStages.bloom.uniforms.selectedBloom = 10
        viewer.scene.postProcessStages.bloom.uniforms.bloomColor = Cesium.Color.fromCssColorString("#fafafa")

        // 隐藏Cesium水印
        viewer.cesiumWidget.creditContainer.style.display = "none"
    } catch (error) {
        console.error('设置场景效果失败:', error)
        throw error
    }
}

// 加载3D模型
const loadTilesets = async (viewer, urls, loadCb) => {
    try {
        const tilesets = urls.map((item) => {
            const { url, options } = item
            let params = { url }
            if (typeof options === "object") {
                Object.assign(params, options)
            }
            const tile = viewer.scene.primitives.add(new Cesium.Cesium3DTileset(params))
            return tile.readyPromise
        })
        let result = await Promise.all(tilesets)
        loadCb && loadCb(result)
        return result
    } catch (error) {
        console.error('加载3D模型失败:', error)
        throw error
    }
}

// 设置默认视角
const setDefaultView = (viewer) => {
    try {
        viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(113.95, 30.19, 34000),
            duration: 2,
            orientation: {
                heading: Cesium.Math.toRadians(35.0),
                pitch: Cesium.Math.toRadians(-37.0),
                roll: 0.0,
            },
        })
    } catch (error) {
        console.error('设置默认视角失败:', error)
        throw error
    }
}

onMounted(async () => {
    try {
        loading.value = true
        const viewer = initViewer("cesium-viewer");
        setScene(viewer);
        dataStore.setViewer(markRaw(viewer))

        const modelUrls = [{
            url: import.meta.env.VITE_MODEL_URL || "http://localhost:8888/model/tileset.json",
            options: {}
        }]

        await loadTilesets(viewer, modelUrls, (tilesets) => {
            dataStore.setTileset(tilesets[0])
            viewer.zoomTo(tilesets[0])
        })
    } catch (error) {
        console.error('初始化失败:', error)
        // 这里可以添加错误提示UI
    } finally {
        loading.value = false
    }
});
</script>

<style>
#cesium-viewer {
    width: 100%;
    height: 100%;
    pointer-events: all;
    position: relative;
}

.loading-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(255, 255, 255, 0.7);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1000;
}
</style>